<!-- 通用上传图片组件 -->
<template>
  <div class="photo-upload-wrap">
    <px-upload
      v-model:file-list="statePhotoList"
      class="photo-upload"
      :class="props.photoType === 'view' ? 'hidden-trigger' : ''"
      list-type="picture-card"
      multiple
      :auto-upload="false"
      accept=".jpg,.png,.jpeg,.gif,.bmp"
      :action="actionUrl"
      :headers="headers"
      :data="props.photoData"
      :before-upload="beforeUpload"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :limit="100"
      :on-change="handleChange"
    >
      <template #trigger>
        <div class="px-upload__trigger">
          <px-icon><Plus /></px-icon>
          <span>图片上传</span>
        </div>
      </template>
      <template #file="{ file }">
        <div>
          <img class="px-upload-list__item-thumbnail" :src="file.url || file.fileUrl" alt="" />
          <span class="px-upload-list__item-actions">
            <span @click="photoPreview">
              <px-icon><zoom-in /></px-icon>
            </span>
            <span v-if="props.photoType === 'view'" @click="photoDownload(file)">
              <px-icon><Download /></px-icon>
            </span>
            <span v-if="props.photoType === 'add' || props.photoType === 'edit'" @click="photoDelete(file)">
              <px-icon><Delete /></px-icon>
            </span>
          </span>
        </div>
      </template>
      <template v-if="props.photoType === 'add' || props.photoType === 'edit'" #tip>
        <div class="px-upload__tip">⽀持jpg/png/jpeg/gif/bmp图片格式，且图片⼤⼩不超过20M</div>
      </template>
    </px-upload>
    <px-image-viewer
      v-if="photoShow"
      :draggable="false"
      :url-list="statePhotoList.map(file => file.url || file.fileUrl)"
      @close="closePhotoPreview"
    />
    <px-button type="primary" :loading="isUpload" @click="uploadPic">Click to upload</px-button>
  </div>
</template>
<script setup lang="ts">
import { reactive, toRefs, watch, getCurrentInstance, ref } from "vue";
import { getToken } from "@/utils/auth";
import { PxMessage, PxImageViewer } from "px-ui";
import { deleteFile } from "@/api/common";
import { uploadPicArray } from "@/api/visual/visualConfig";
// 调用父级-改变图片列表方法，查看时不调用
const emits = defineEmits(["changePhotoList"]);
// 父级传过来的值
const props = defineProps({
  // 图片上传类型add：新增，edit：编辑，view：查看
  photoType: {
    type: String,
    default: "add",
    required: true
  },
  // 文档上传接口url
  actionUrl: {
    type: String,
    default: "/ifp/sharing/api/v1/file/upload",
    required: false
  },
  // 图片上传接口数据
  photoData: {
    type: Object,
    default: () => ({}),
    required: true
  },
  // 图片上传类型为edit/view时，已上传的图片列表
  photoList: {
    type: Array,
    default: () => [],
    required: true
  }
});
const isUpload = ref(false);
// 页面本身的值
const { proxy }: any = getCurrentInstance();
const state = reactive<any>({
  headers: {
    Authorization: "Bearer " + getToken().accessToken || "",
    facCode: localStorage.getItem("facCode") || ""
  },
  photoList: [], // 图片列表
  photoShow: false // 图片预览显示
});
const { headers, photoList: statePhotoList, photoShow } = toRefs(state);
let picList = [];
// 监视图片上传类型
watch(
  () => [props.photoType, props.photoList],
  val => {
    statePhotoList.value = val[1];
  },
  { immediate: true }
);

// 上传图片之前判断大小及格式
const beforeUpload = rawFile => {
  const acceptList = ["jpg", "png", "jpeg", "gif", "bmp"];
  let fileType = rawFile.name.split(".").pop().toLowerCase();
  if (acceptList.indexOf(fileType) === -1) {
    PxMessage.error("只能上传 jpg/png/jpeg/gif/bmp 格式的图片");
    return false;
  } else if (rawFile.size / 1024 / 1024 > 20) {
    PxMessage.error("上传图片大小不能超过20M");
    return false;
  }
  return true;
};
// 上传成功状态
const uploadSuccess = response => {
  if (response.length > 0) {
    // 上传成功，通过success为true判断
    PxMessage.success("图片上传成功");

    emits("changePhotoList", statePhotoList.value);
  } else {
    // 后台返回上传失败信息
    statePhotoList.value = [];
    PxMessage.error(response);
    emits("changePhotoList", statePhotoList.value);
  }
};
// 上传失败状态
const uploadError = error => {
  // 此处由于后端未处理，前端先统一写"图片上传失败，请重试"

  statePhotoList.value = [];
  PxMessage.error("图片上传失败，请重试");
  emits("changePhotoList", statePhotoList.value);
};
// 图片预览
const photoPreview = () => {
  photoShow.value = true;
};
// 关闭图片预览
const closePhotoPreview = () => {
  photoShow.value = false;
};
// 下载图片
const photoDownload = file => {
  const params = {
    id: file?.response?.data?.id ? file?.response?.data?.id : file.id,
    fileName: file?.response?.data?.fileName ? file?.response?.data?.fileName : file.fileName,
    moduleName: props.photoData?.moduleName
  };
  proxy.download("post", "/sharing/api/v1/file/download", params, file.fileName);
};
// 删除图片
const photoDelete = async file => {
  // const id = file?.response?.data?.id ? file?.response?.data?.id : file.id;
  // const params = {
  //   fileId: [id]
  // };
  // await deleteFile(params);
  // PxMessage.success("图片删除成功");
  // photoList.value = photoList.value.filter(item => item !== file);
  emits("changePhotoList", statePhotoList.value);
};
const handleChange = (file, fileList) => {
  picList = fileList.map(m => m.raw);
};
const uploadPic = async () => {
  isUpload.value = true;

  const formData = new FormData();
  formData.append("moduleName", props.photoData.moduleName);

  picList.forEach(file => {
    formData.append("files", file);
  });

  try {
    const res = await uploadPicArray(formData);
    uploadSuccess(res);
  } catch (error) {
    uploadError(error);
  }
  isUpload.value = false;
};
</script>

<style lang="scss" scoped>
.photo-upload-wrap {
  .photo-upload {
    :deep(.px-upload-list--picture-card) {
      --px-upload-list-picture-card-size: 96px;

      position: relative;
      min-height: 96px;

      .px-upload--picture-card {
        --px-upload-picture-card-size: 96px;

        position: absolute;
        top: 0;
        left: 0;
        display: block;
        text-align: center;
      }

      .px-upload-list__item:first-of-type {
        margin-left: 104px;
      }

      .px-upload__trigger {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 100%;
        color: #666;

        span {
          font-size: 14px;
          color: rgb(0 0 0 / 45%);
        }
      }

      .px-upload__tip {
        font-size: 12px;
        color: rgb(0 0 0 / 60%);
      }
    }

    &.hidden-trigger {
      :deep(.px-upload-list--picture-card) {
        min-height: 0;

        .px-upload--picture-card {
          display: none;
        }

        .px-upload-list__item:first-of-type {
          margin-left: 0;
        }
      }
    }
  }
}
</style>
